const queryString = params => '?' + Object
    .keys(params)
    .map(key => `${key}=${encodeURIComponent(params[key])}`)
    .join('&');

const request = (baseUrl, partialUrl, body, query, method = 'GET', contentType = 'Application/JSON') => {
    const needContentType = ['POST', 'PUT'].includes(method.toUpperCase());

    return new Promise((success, fail) => uni.request({
        url: baseUrl + partialUrl + (query ? queryString(query) : ''),
        method,
        data: body,
        header: {
            ...needContentType ? {
                'Content-Type': contentType
            } : {}
        },
        success,
        fail
    }))
}

export class API {
    constructor(baseUrl, before, after) {
        // BASE URL
        this.baseUrl = baseUrl;

        // 两个拦截器。
        this.before = before;
        this.after = after;
    }

    _request(partialUrl, body, query, method, contentType) {
        // 执行请求前拦截器。
        this.before && this.before();
        const promise = request(this.baseUrl, partialUrl, body, query, method, contentType);

        promise.finally(() => this.after && this.after());
        return promise;
    }

    get(partialUrl, query) {
        return this._request(partialUrl, undefined, query);
    }

    'delete'(partialUrl, query) {
        return this._request(partialUrl, undefined, query, 'DELETE');
    }

    post(partialUrl, body, query, contentType) {
        return this._request(partialUrl, body, query, 'POST', contentType)
    }

    put(partialUrl, body, query, contentType) {
        return this._request(partialUrl, body, query, 'PUT', contentType)
    }
}